<template>
  <div>
    <el-card style="margin-bottom: 10px">
      <category-selector :disabled="!isShowAttrList" />
    </el-card>

    <el-card>
      <div v-if="isShowAttrList">
        <el-button
          type="primary"
          :icon="Plus"
          :disabled="!categoryStore.getCategory3Id"
          @click="showAdd"
          v-has="'btn.Attr.add'"
          >添加属性</el-button
        >
        <el-table :data="attrList" border row-key="id">
          <el-table-column label="序号" type="index" width="80" align="center">
          </el-table-column>
          <el-table-column prop="attrName" label="属性名称" width="150">
          </el-table-column>
          <el-table-column label="属性值列表">
            <template v-slot="{ row }">
              <el-tag
                style="margin-right: 5px"
                type="success"
                v-for="item in row.attrValueList"
                :key="item.id"
                >{{ item.valueName }}</el-tag
              >
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150">
            <template v-slot="{ row }">
              <el-button
                style="margin-right: 10px"
                @click="showUpdate(row)"
                title="修改属性"
                type="primary"
                :icon="Edit"
                size="small"
                v-has="'btn.Attr.update'"
              ></el-button>
              <el-popconfirm
                :title="`确定删除${row.attrName}吗?`"
                @confirm="remove(row.id)"
              >
                <template #reference>
                  <el-button
                    v-has="'btn.Attr.remove'"
                    title="删除属性"
                    type="danger"
                    :icon="Delete"
                    size="small"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else>
        <span>属性名</span>
        <el-input
          style="width: 200px; margin-left: 20px"
          v-model="attr.attrName"
          placeholder="请输入属性名"
        ></el-input>
        <br />

        <div style="margin: 20px 0">
          <el-button
            :disabled="!attr.attrName"
            type="primary"
            icon="el-icon-plus"
            @click="addValue"
            >添加属性值</el-button
          >
          <el-button @click="isShowAttrList = true">取消</el-button>
        </div>

        <el-table
          style="margin-bottom: 20px"
          :data="attr.attrValueList"
          v-loading="loading"
        >
          <el-table-column label="序号" type="index" width="80">
          </el-table-column>
          <el-table-column label="属性值名称">
            <template v-slot="{ row, $index }">
              <el-input
                :ref="(input: any) => inputsRef[$index] = input"
                @blur="showSpan(row, $index)"
                v-model="row.valueName"
                v-if="row.isShowEdit"
                size="small"
              ></el-input>
              <span
                style="display: inline-block; width: 100%"
                v-else
                @click="showInput(row, $index)"
                >{{ row.valueName }}</span
              >
            </template>
          </el-table-column>
          <el-table-column label="操作">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                :title="`确定删除${row.valueName}吗?`"
                @confirm="
                  () => {
                    attr.attrValueList.splice($index, 1);
                  }
                "
              >
                <template #reference>
                  <el-button
                    title="删除"
                    type="danger"
                    :icon="Delete"
                    size="small"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>

        <el-button type="primary" @click="save" :disabled="isSaveDisabled"
          >保存</el-button
        >
        <el-button @click="isShowAttrList = true">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
export default {
  name: "Attr",
};
</script>

<script lang="ts" setup>
import cloneDeep from "lodash/cloneDeep";
import { nextTick, computed, ref, reactive, watch } from "vue";
import {
  ElCard,
  ElButton,
  ElTable,
  ElTableColumn,
  ElPopconfirm,
  ElInput,
  ElTag,
  ElMessage,
} from "element-plus";
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import CategorySelector from "@/components/CategorySelector/index.vue";
import type {
  AttrListModel,
  AttrModel,
  AttrValueModel,
} from "@/api/product/model/attrModel";
import {
  getAttrListApi,
  addOrUpdateAttrApi,
  deleteAttrApi,
} from "@/api/product/attr";
import { useCategoryStore } from "@/stores/category";

const categoryStore = useCategoryStore();
const loading = ref(false);
const attrList = ref<AttrListModel>([]);
const attr = reactive<AttrModel>({
  // 要添加或更新的属性对象
  attrName: "", // 属性名
  attrValueList: [], // 属性值列表
  categoryId: -1,
  categoryLevel: 3,
});
const isShowAttrList = ref<boolean>(true);
const inputsRef = ref<HTMLInputElement[]>([]);

/* 
  获取属性列表显示
  */
const getAttrList = async () => {
  loading.value = true;
  attrList.value = await getAttrListApi({
    category1Id: categoryStore.category1Id as number,
    category2Id: categoryStore.category2Id as number,
    category3Id: categoryStore.category3Id as number,
  });
  loading.value = false;
};

// 等category3Id有值的时候才需要发送请求
watch(
  // 监视的数据
  () => categoryStore.category3Id,
  // 触发的函数
  async (category3Id) => {
    if (!category3Id) {
      attrList.value = [];
      return;
    }
    getAttrList();
  },
  // 一上来触发
  // 从添加属性组件切换回来时会触发
  { immediate: true }
);

// 计算保存按钮是否是禁用
const isSaveDisabled = computed(() => {
  const { attrName, attrValueList } = attr;
  const hasName = !!attrName;
  const hasValue = attrValueList.some((attrValue) => attrValue.valueName);
  return !hasName || !hasValue;
});

/**
 * 删除属性
 * @param id
 */
const remove = async (id: number) => {
  await deleteAttrApi(id);
  ElMessage.success("删除成功");
  getAttrList();
};

/* 
  保存要添加或更新的属性
  */
const save = async () => {
  // 添加必要的属性
  attr.categoryId = categoryStore.category3Id as number;

  // 对要提交的数据进行特定处理/整理操作(开发经常做)
  // 处理1: 过滤掉没有属性值名称的属性值对象
  // 处理2: 删除属性值对象中的edit属性
  attr.attrValueList = attr.attrValueList.filter((value) => {
    if (value.valueName) {
      delete value.isShowEdit;
      return true;
    }
    return false;
  });

  // 发请求
  await addOrUpdateAttrApi(attr);
  // 提示
  ElMessage.success("保存成功");
  // 回到列表页面
  isShowAttrList.value = true;
  // 重新获取列表显示
  getAttrList();
};

/**
 * 添加一个属性值
 */
const addValue = () => {
  // 向attr.attrValueList中添加一个属性值对象:
  attr.attrValueList.push({
    valueName: "",
    attrId: attr.id,
    isShowEdit: true,
  });
  // 自动获取焦点:
  nextTick(() => {
    inputsRef.value[attr.attrValueList.length - 1].focus();
  });
};

/**
 * 显示文本
 * @param row 属性值对象
 * @param index 下标
 */
const showSpan = (row: AttrValueModel, index: number) => {
  // 如果没有输入, 删除这条数据
  if (!row.valueName) {
    attr.attrValueList.splice(index, 1);
    return;
  }
  // 变为查看模式
  row.isShowEdit = false;
};

/**
 * 显示输入框
 * @param row  属性值对象
 * @param index 下标
 */
const showInput = (row: AttrValueModel, index: number) => {
  // 显示输入框
  row.isShowEdit = true;

  // 显示输入框后, 自动获取焦点
  nextTick(() => {
    inputsRef.value[index].focus();
  });
};

/**
 * 显示添加界面
 */
const showAdd = () => {
  // 重置attr
  Object.assign(attr, {
    attrName: "",
    attrValueList: [],
    categoryId: categoryStore.category3Id as number,
    categoryLevel: 3,
  });

  // 显示添加界面
  isShowAttrList.value = false;
};

/**
 * 显示更新界面
 * @param row 属性对象
 */
const showUpdate = (row: AttrModel) => {
  // 保存要更新的attr
  Object.assign(attr, cloneDeep(row));
  // 显示更新界面
  isShowAttrList.value = false;
};
</script>
